package com.fingard.dsp.bank.directbank.hzcb01;

import java.text.DecimalFormat;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextWriter;


public class HZCB01Base extends DirectBase implements ITcpClient {
    protected static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    protected static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? AND BANKCODE=?;";


    protected static final String banks="7003";
    protected String txCode = "";
    protected String signature = "";
    protected String[] tmpSign = new String[]{"", ""};
    private static final String STR_FORMAT = "00000000";
    DecimalFormat decimalFormat = new DecimalFormat(STR_FORMAT);


    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.Time12Format.format(tmpDateNow);
    }

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter) throws Exception {
        if (StringHelper.isNullOrEmpty(txCode)) {
            throw new Exception("未赋值txCode");
        }
        Date date = new Date();
        //写入通用的头部节点
        //报文长度（8位）不足左补0+ 报文类型（2位）01+交易码（6位）
        xmlWriter.writeStartDocByDeclaration("01" + txCode + "<?xml version=\"1.0\" encoding=\"GBK\"?>");
        xmlWriter.writeStartElement("HZBANKB2C");
        xmlWriter.writeStartElement("ebank");
        xmlWriter.writeStartElement("common");
        xmlWriter.writeElementString("TxId", bankFront.operator);
        xmlWriter.writeElementString("TxDate", Format.Date8Format.format(date));
        xmlWriter.writeElementString("TxTime", Format.Time6Format.format(date));
        xmlWriter.writeElementString("TxCode", txCode);//交易代码
        xmlWriter.writeElementString("TxChan", "01");//交易渠道 默认01
        xmlWriter.writeElementString("TxVer", "1.00");//版本号 填入默认值：1.00
        xmlWriter.writeEndElement();
    }

    protected String[] sendToBank(String p_reqStr) throws Exception{
        return sendToBank(p_reqStr,"","");
    }

    protected String[] sendToBank(String p_reqStr, String transType, String commandCode) throws Exception {
        String[] retStr = new String[]{"", ""};
        if (StringHelper.hasAnyChar(transType) && StringHelper.hasAnyChar(commandCode)) {
            this.detailSimulateForBank(bankFront.bankCode, transType, commandCode, p_reqStr, retStr);
            if (retStr[1].length() > 0) {
                return retStr;
            }
        }
        String url = bankFront.serverURL;
        if("DOWNLOADRECEIPT".equals(transType) && StringHelper.hasAnyChar(bankFront.serverDownload)){
            url = bankFront.serverDownload;
        }

        WriteBankLogLn("1.提交银行的地址：" + url);
        int n = p_reqStr.getBytes("GBK").length;
        String p_head = decimalFormat.format(n);
        String p_string = p_head+p_reqStr;
        WriteBankLogStep2(p_string);
        WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = getCharset();
        byte[] tmpToWriteBytes = p_string.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogStep3(retStr[1]);

        return retStr;
    }

    protected boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if ("000000".equals(retCode) || "0".equals(retCode)) {
                return true;
            }
        }
        return false;
    }

    //处理数据签名
    protected Boolean signnatrue(String signXml) throws Exception {
        WriteBankLogLn("1.银行签名地址:"+bankFront.serverIP + ":" + bankFront.signPort);

        //发送银行前置
        try {
            TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.signPort), this);

            String tmpCharset = getCharset();
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(signXml);
            //组装签名报文,格式为：签名原文#02
            stringBuilder.append("#02\n");
            byte[] tmpBytesBody = stringBuilder.toString().getBytes(tmpCharset);
            WriteBankLogStep2(stringBuilder.toString());
            TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesBody);
            tmpSign[0] = tmpReceiver.connState;
            if (tmpReceiver.recBytes != null) {
                tmpSign[1] = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
            } else {
                tmpSign[1] = tmpReceiver.getConnMsg();
            }
            if (!tmpReceiver.isCompleted) {
                WriteBankLogLn(tmpReceiver.getConnMsg());
            }
            WriteBankLogLn("3.签名返回的结果：" + tmpSign[1]);
            if (tmpSign[0].length() == 0) {
                if (tmpSign[1].contains("#00")) {
                    WriteBankLogLn("签名成功");
                    signature = tmpSign[1].split("#")[0].toString();
                    /*signature = signature.replace("\r", "").replace("\n", "");*/
                    return true;
                } else {
                    WriteBankLogLn("签名失败");
                    return false;
                }
            } else {
                WriteBankLogLn("签名失败");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn("与银行签名端口通讯失败；详细信息：" + tmpSign[1]);
        }
        return false;
    }

    @Override
    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            String tmpCharset = "GBK";
            String tmpRecNow = new String(p_receiver.recBytes, 0, p_receiver.readedLength, tmpCharset);
            if (tmpRecNow.indexOf("</HZBANKB2C>") >= 0) {
                p_receiver.contentLength = p_receiver.readedLength;
                p_receiver.contentStartIndex = 0;
            }
        }
    }

    public String clearWarpAndBlank(String data) {
        return data.replace("\r", "").replace("\n", "").replace(" ", "");
    }

    public String clearWrap(String data){
        return data.replace("\r","").replace("\n","");
    }
    public String getDataSignData(XmlTextWriter xmlTextWriter) {
        String data = xmlTextWriter.toXmlString();
        return clearWarpAndBlank(data.substring(data.indexOf("<ebank>") , data.indexOf("</ebank>")+8));
    }

    public String getDataSendBank(String bankData){
        String data = clearWrap(bankData.substring(0,bankData.indexOf("<HZBANKB2C>")))+clearWarpAndBlank(bankData.substring(bankData.indexOf("<HZBANKB2C>"),bankData.indexOf("<ebank>")))+clearWarpAndBlank(bankData.substring(bankData.indexOf("<ebank>"),bankData.indexOf("</ebank>")+8))+clearWarpAndBlank(bankData.substring(bankData.indexOf("</ebank>")+8));
        return data;
    }

    /**
     * 清算标志 1=SM00=线上  2=SM01=线下
     * @param payType
     * @return
     */
    protected String getPayType(String payType){
        String result="";
        if("SM00".equals(payType) || "SM01".equals(payType)){
            result= "SM00".equals(payType) ? "1" : "0";
        }else if("1".equals(payType) || "0".equals(payType)){
            result= "1".equals(payType) ? "SM00" : "SM01";
        }
        return result;
    }

    /**
     * 签收标志  SU00同意签收  SU01拒绝签收
     * @param respFlag
     * @return
     */
    protected String getRespFlag(String respFlag){
        String result="";
        if("SU00".equals(respFlag) || "SU01".equals(respFlag)){
            result= "SU00".equals(respFlag) ? "1" : "2";
        }else if("1".equals(respFlag) || "2".equals(respFlag)){
            result= "1".equals(respFlag) ? "SU00" : "SU01";
        }
        return result;
    }

    /**
     * 获取拒付理由代码
     * DC00、与自己有直接债权债务关系的持票人未履行约定义务；
     * DC01、持票人以欺诈、偷盗或者胁迫等手段取得票据；
     * DC02、持票人明知有欺诈、偷盗或者胁迫等情形，出于恶意取得票据；
     * DC03、持票人明知债务人与出票人或者持票人的前手之间存在抗辩事由而取得票据；
     * DC04、持票人因重大过失取得不符合《票据法》规定的票据；
     * DC05、超过提示付款期；
     * DC06、被法院冻结或收到法院止付通知书；
     * DC07、票据未到期；
     * DC08、商业承兑汇票承兑人账户余额不足。
     * DC09、其他（必须注明）
     * @param unPayCode
     * @return
     */
    protected String getStddshnrcdByUnPayCode(String unPayCode){
        String stddshnrcd="";
        if ("99".equals(unPayCode)) {
            stddshnrcd="DC09";//拒付代码
        } else if (Integer.parseInt(unPayCode) > 0 && Integer.parseInt(unPayCode) <= 9) {
            stddshnrcd="DC0" + (Integer.parseInt(unPayCode) - 1);
        }
        return stddshnrcd;
    }

    /**
     * 付息方式:1：卖方付息;2：买方付息;3：协议付息
     * @param payInterestType
     * @return
     */
    protected String getPayInterestTypeToBank(String payInterestType) throws Exception{
        String result="";
        if(StringHelper.isNullOrEmpty(payInterestType)){
            result="02";//默认卖方付息
        }else {
            switch (Integer.parseInt(payInterestType)){
                case 1:result="02";break;
                case 2:result="01";break;
                case 3:result="03";break;
                default:throw new Exception("付息方式异常，请联系系统管理员");
            }
        }
        return result;
    }

    /**
     * 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押
     * 7-出票保证 8-承兑保证 9-背书保证 10-贴现
     * 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
     * @param busiType
     * @return
     */
    protected String getBusiType(String busiType,String overdueFlag) throws Exception{
        String result="";
        switch (Integer.parseInt(busiType)){
            case 2:result="02";break;//可承兑
            case 3:result="03";break;//可收票
            case 4:result="05";break;//可背书
            case 5:result="15";break;//可质押
            case 6:result="16";break;//可质押解除
            case 7:result="14";break;//出票保证
            case 8:result="13";break;//承兑保证
            case 9:result="12";break;//背书保证
            case 10:result="06";break;//贴现
            case 12:
                if("1".equals(overdueFlag)){
                    result="17";//正常
                }else if("2".equals(overdueFlag)){
                    result="18";//逾期
                }break;//提示付款
            default:throw new Exception("银行暂不支持此业务类型");
        }
        return result;
    }

    /**
     * 签收业务映射
     * @param respType 1-承兑应答 2-收票应答 3-背书转让应答 4-回购式贴现赎回应答
     *                5-质押解除应答 6-提示付款应答 7-保证应答 8-同意清偿应,9-质押签收
     * @param proPayType  逾期标志 1非逾期 2逾期
     * @return
     */
    protected String getStdinfotypByRespType(String respType,String proPayType){
        String stdinfotyp="";
        if(StringHelper.hasAnyChar(respType)){
            switch (Integer.parseInt(respType)){
                case 1:stdinfotyp="02";break;//承兑签收
                case 2:stdinfotyp="03";break;//收票签收
                case 3:stdinfotyp="05";break;//背书签收
                //case 4:"";break;//回购式贴现赎回签收
                case 9:stdinfotyp="15";break;//质押签收
                case 5:stdinfotyp="16";break;//质押解除签收
                case 7:stdinfotyp="13";break;//14出票人提示保证签收、13承兑人提示保证签收、12背书人提示保证签收
                case 6:if("1".equals(proPayType)){
                    stdinfotyp="17";//非逾期提示付款签收
                }else if("2".equals(proPayType)){
                    stdinfotyp="18";//逾期提示付款签收
                }break;
                case 8:stdinfotyp="20";break;//同意清偿签收
                default:WriteBankLogLn("银行不支持此业务类型的签收");break;
            }
        }
        return stdinfotyp;
    }

    /**
     * 签收查询业务类型映射
     * @param busiType 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押
     *                 7-出票保证 8-承兑保证 9-背书保证 10-贴现
     *                 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
     * @param overdueFlag  逾期标志 1非逾期 2逾期
     * @return
     */
    protected String getStdinfotypByBusiType(String busiType,String overdueFlag){
        String stdinfotyp="";
        if(StringHelper.hasAnyChar(busiType)){
            switch (Integer.parseInt(busiType)){
                case 2:stdinfotyp="02";break;//承兑签收
                case 3:stdinfotyp="03";break;//收票签收
                case 4:stdinfotyp="05";break;//背书签收
                case 5:stdinfotyp="15";break;//质押签收
                case 6:stdinfotyp="16";break;//质押解除签收
                case 7:stdinfotyp="14";break;//出票人提示保证签收
                case 8:stdinfotyp="13";break;//承兑人提示保证签收
                case 9:stdinfotyp="12";break;//背书人提示保证签收
                case 12:if("1".equals(overdueFlag)){
                    stdinfotyp="17";//非逾期提示付款签收
                }else if("2".equals(overdueFlag)){
                    stdinfotyp="18";//逾期提示付款签收
                }break;
                case 13:stdinfotyp="19";break;//追索通知签收
                case 14:stdinfotyp="20";break;//同意清偿签收
                default:WriteBankLogLn("银行不支持此业务类型的签收");break;
            }
        }
        return stdinfotyp;
    }
}
